package org.piggy.core.filter.loadbalance;

import lombok.extern.slf4j.Slf4j;
import org.piggy.common.config.ServiceInstance;
import org.piggy.common.constants.FilterConst;
import org.piggy.common.rule.Rule;
import org.piggy.core.context.GatewayContext;
import org.piggy.core.filter.Filter;
import org.piggy.core.filter.FilterAspect;
import org.piggy.core.filter.loadbalance.rule.*;
import org.piggy.core.request.GatewayRequest;

@Slf4j
@FilterAspect(id = FilterConst.LOAD_BALANCE_FILTER_ID, name = FilterConst.LOAD_BALANCE_FILTER_NAME, order = FilterConst.LOAD_BALANCE_FILTER_ORDER)
public class LoadBalanceFilter implements Filter {
    @Override
    public void doFilter(GatewayContext gatewayContext) {
        Rule configRule = gatewayContext.getRule();
        if(configRule != null){
            LoadBalanceGatewayRule loadBalanceRule;
            Rule.LoadBalanceConfig loadBalanceConfig = configRule.getLoadBalanceConfig();
            String type;
            if(loadBalanceConfig == null){
                type = FilterConst.LOAD_BALANCE_STRATEGY_RANDOM;
            }else {
                type = loadBalanceConfig.getType();
                if(type == null){
                    type = FilterConst.LOAD_BALANCE_STRATEGY_RANDOM;
                }
            }
            switch (type) {
                case FilterConst.LOAD_BALANCE_STRATEGY_CONSISTENT_HASH->
                        loadBalanceRule = ConsistentHashLoadBalanceRule.getInstance();
                case FilterConst.LOAD_BALANCE_STRATEGY_WEIGHT ->
                        loadBalanceRule = WeightLoadBalanceRule.getInstance();
                case FilterConst.LOAD_BALANCE_STRATEGY_ROUND_ROBIN ->
                        loadBalanceRule = RoundRobinLoadBalanceRule.getInstance();
                default ->
                        loadBalanceRule = RandomLoadBalanceRule.getInstance();
            }
            ServiceInstance serviceInstance = loadBalanceRule.choose(gatewayContext);
            GatewayRequest gatewayRequest = gatewayContext.getGatewayRequest();
            gatewayRequest.setModifyHost(serviceInstance.getServiceInstanceId());
            gatewayRequest.setIp(serviceInstance.getIp());
            gatewayRequest.setPort(serviceInstance.getPort());
        }
    }
}
